package com.flower.subject.domain.service.impl;


import com.alibaba.fastjson.JSON;
import com.flower.subject.domain.config.ThreadPoolConfig;
import com.flower.subject.domain.convent.SubjectLabelConverter;
import com.flower.subject.domain.entity.SubjectCategoryBO;
import com.flower.subject.domain.entity.SubjectLabelBO;

import com.flower.subject.domain.service.SubjectLabelDomainService;
import com.flower.subject.enums.CategoryTypeEnum;
import com.flower.subject.enums.IsDeletedFlagEnum;
import com.flower.subject.infra.basic.entity.SubjectCategory;
import com.flower.subject.infra.basic.entity.SubjectLabel;

import com.flower.subject.infra.basic.entity.SubjectMapping;
import com.flower.subject.infra.basic.service.SubjectCategoryService;
import com.flower.subject.infra.basic.service.SubjectLabelService;
import com.flower.subject.infra.basic.service.SubjectMappingService;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author lavender
 * @version 1.0
 * @date 2024-07-03 11:30
 */

@Service
@Slf4j
public class SubjectLabelDomainServiceImpl implements SubjectLabelDomainService {

    @Resource
    private SubjectLabelService subjectLabelService;

    @Resource
    private SubjectMappingService subjectMappingService;

    @Resource
    private SubjectCategoryService subjectCategoryService;

    @Resource
    private ThreadPoolExecutor threadPoolExecutor;

    private Cache<String,String> localCache = CacheBuilder.newBuilder()
            .maximumSize(5000)
            .expireAfterWrite(10, TimeUnit.SECONDS).build();



    public void add(SubjectLabelBO bo) {
        SubjectLabel subjectLabel = SubjectLabelConverter.INSTANT.convertToSubjectLabel(bo);
        subjectLabel.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode());
        subjectLabelService.insert(subjectLabel);


    }


    public List<SubjectCategoryBO> queryPrimaryCategory(SubjectCategory subjectCategory) {


        return null;
    }

    public List<SubjectCategoryBO> queryCateGory(SubjectCategoryBO subjectCategoryBO) {


        return null;
    }

    public Boolean update(SubjectLabelBO bo) {
        SubjectLabel subjectLabel = SubjectLabelConverter.INSTANT.convertToSubjectLabel(bo);
        int count = subjectLabelService.update(subjectLabel);
        return count > 0;
    }

    public Boolean delete(SubjectLabelBO bo) {
        SubjectLabel subjectLabel = SubjectLabelConverter.INSTANT.convertToSubjectLabel(bo);
        subjectLabel.setIsDeleted(IsDeletedFlagEnum.DELETE.getCode());
        int count = subjectLabelService.update(subjectLabel);
        return count > 0;

    }

    @SneakyThrows
    @Override
    public List<SubjectLabelBO> queryLabelByCategoryId(SubjectLabelBO subjectLabelBO) {

        String cacheKey = "Label" + subjectLabelBO.getCategoryId();
        String content = localCache.getIfPresent(cacheKey);
        SubjectCategory subjectCategory = new SubjectCategory();
        //如果 当前分类是一级分类 则查询所有标签
        if(StringUtils.isBlank(content)){
            subjectCategory = subjectCategoryService.queryById(subjectLabelBO.getCategoryId());
            localCache.put(cacheKey, JSON.toJSONString(subjectCategory));
        }else {
            subjectCategory = JSON.parseObject(content, SubjectCategory.class);
        }

//        SubjectCategory subjectCategory = subjectCategoryService.queryById(subjectLabelBO.getCategoryId());




        // 一次获取标签信息 todo future并发
//        List<FutureTask<Map<Long, List<SubjectLabelBO>>>> futureTasks = new LinkedList<>();
//
//        Map<Long, List<SubjectLabelBO>> map = new HashMap<>();
//        FutureTask<Map<Long, List<SubjectLabelBO>>> futureTask = new FutureTask<>(()->
//                getSubjectLabelBOS(subjectLabelBO.getCategoryId())
//        );
//        futureTasks.add(futureTask);
//        threadPoolExecutor.submit(futureTask);
//
//        for (FutureTask<Map<Long, List<SubjectLabelBO>>> futureTaskResult : futureTasks){
//            Map<Long, List<SubjectLabelBO>> resultMap = futureTaskResult.get();
//            if(CollectionUtils.isEmpty(resultMap)){
//                continue;
//            }
//            map.putAll(resultMap);
//
//        }

        if(CategoryTypeEnum.PRIMARY.getCode().equals(subjectCategory.getCategoryType())){
            SubjectLabel subjectLabel = new SubjectLabel();

            List<SubjectLabel> list = subjectLabelService.queryByCondition(subjectLabel);
            List<SubjectLabelBO> labelBOS = SubjectLabelConverter.INSTANT.convertBoTOSubjectLabel(list);
            return labelBOS;
        }
        Integer categoryId = subjectLabelBO.getCategoryId();

        SubjectMapping subjectMapping = new SubjectMapping();
        subjectMapping.setCategoryId(categoryId.longValue());
        List<SubjectMapping> mappingList = subjectMappingService.queryLabelId(subjectMapping);
        List<Long> labelIdList = mappingList.stream().map(SubjectMapping::getLabelId).collect(Collectors.toList());
        List<SubjectLabel> labelList = subjectLabelService.batchQueryById(labelIdList);
        List<SubjectLabelBO> boList = new LinkedList<>();
        labelList.forEach(label -> {
            SubjectLabelBO bo = new SubjectLabelBO();
            bo.setId(label.getId());
            bo.setLabelName(label.getLabelName());
            bo.setCategoryId(categoryId);
            boList.add(bo);
        });


        return boList;
    }

    // futuretask 异步查询
    private Map<Long,List<SubjectLabelBO>>  getSubjectLabelBOS(Integer categoryId) {
        Map<Long,List<SubjectLabelBO>> labelMap = new HashMap<>();
        SubjectMapping subjectMapping = new SubjectMapping();
        subjectMapping.setCategoryId(categoryId.longValue());
        List<SubjectMapping> mappingList = subjectMappingService.queryLabelId(subjectMapping);
        List<Long> labelIdList = mappingList.stream().map(SubjectMapping::getLabelId).collect(Collectors.toList());
        List<SubjectLabel> labelList = subjectLabelService.batchQueryById(labelIdList);
        List<SubjectLabelBO> boList = new LinkedList<>();
        labelList.forEach(label -> {
            SubjectLabelBO bo = new SubjectLabelBO();
            bo.setId(label.getId());
            bo.setLabelName(label.getLabelName());
            bo.setCategoryId(categoryId);
            boList.add(bo);
        });
        return null;
    }
}
